﻿using System.Data.Entity;
//using Anmlz.Data.Helpers;
//using Anmlz.Data.SampleData;
using System;
using Anmlz.Services;

namespace Anmlz.Data
{
    using Anmlz.Model.Entities;
    using System.Collections.Generic;
    using System.IO;
    using System.Diagnostics;
    using System.Reflection;

    using Anmlz.Services.Contracts;

    public class AnmlzDatabaseInitializer
    {
        private readonly ISampleTextGenerator _sampleTextGenerator;
        private readonly ICryptService _cryptService;
        private readonly IGeoParser _geoParser;
        Random rnd;
        public AnmlzDatabaseInitializer(ISampleTextGenerator sampleTextGenerator, ICryptService cryptService, IGeoParser geoParser)
        {
            this._sampleTextGenerator = sampleTextGenerator;
            this._cryptService = cryptService;
            this._geoParser = geoParser;
            this.rnd = new Random();
        }

        public void Seed(AnmlzDbContext context)
        {
            AddRoles(context);
            AddAccountTypes(context);

            AddCountries(context);
            AddCities(context);

            AddCurrencies(context);

            AddCreatureTypes(context);
            AddCreatureSizes(context);

            AddCreatureCharacteristics(context);
            // AddCreatureColors(context);
            AddBreedGroups(context);
            //  AddBreeds(context);

            // AddFakeData(context);
            context.SaveChanges();
        }

        private void AddCreatureCharacteristics(AnmlzDbContext context)
        {
            context.CreatureCharacteristics.Add(new CreatureCharacteristic()
                                                    {
                                                        Id = (int)CreatureCharacteristics.Adaptability,
                                                        CreatureTypeId = (int)CreatureTypes.Dog,
                                                        NameEn = "Adaptability",
                                                        NameRu = "Адаптируемость",
                                                        Scale = 5
                                                    });
            context.CreatureCharacteristics.Add(new CreatureCharacteristic()
            {
                Id = (int)CreatureCharacteristics.CatFriendly,
                CreatureTypeId = (int)CreatureTypes.Dog,
                NameEn = "Cat Friendly",
                NameRu = "Терпимость к котам",
                Scale = 11
            });
            context.CreatureCharacteristics.Add(new CreatureCharacteristic()
            {
                Id = (int)CreatureCharacteristics.DogFriendly,
                CreatureTypeId = (int)CreatureTypes.Dog,
                NameEn = "Dog Friendly",
                NameRu = "Терпимость к собакам",
                Scale = 11
            });
            context.CreatureCharacteristics.Add(new CreatureCharacteristic()
            {
                Id = (int)CreatureCharacteristics.GoodWithKids,
                CreatureTypeId = (int)CreatureTypes.Dog,
                NameEn = "Good with Kids",
                NameRu = "Терпимость к детям",
                Scale = 11
            });
            context.CreatureCharacteristics.Add(new CreatureCharacteristic()
            {
                Id = (int)CreatureCharacteristics.Grooming,
                CreatureTypeId = (int)CreatureTypes.Dog,
                NameEn = "Frequency of grooming",
                NameRu = "Частота стрижки",
                Scale = 11
            });
            context.CreatureCharacteristics.Add(new CreatureCharacteristic()
            {
                Id = (int)CreatureCharacteristics.Hypoallergenic,
                CreatureTypeId = (int)CreatureTypes.Dog,
                NameEn = "Hypoallergenic",
                NameRu = "Гипоаллергенность",
                Scale = 1
            });
            context.CreatureCharacteristics.Add(new CreatureCharacteristic()
            {
                Id = (int)CreatureCharacteristics.Intelligence,
                CreatureTypeId = (int)CreatureTypes.Dog,
                NameEn = "Intelligence",
                NameRu = "Интеллект",
                Scale = 11
            });
            context.CreatureCharacteristics.Add(new CreatureCharacteristic()
            {
                Id = (int)CreatureCharacteristics.Popularity,
                CreatureTypeId = (int)CreatureTypes.Dog,
                NameEn = "Popularity",
                NameRu = "Популярность",
                Scale = 11
            });
            context.CreatureCharacteristics.Add(new CreatureCharacteristic()
            {
                Id = (int)CreatureCharacteristics.Shedding,
                CreatureTypeId = (int)CreatureTypes.Dog,
                NameEn = "Shedding",
                NameRu = "Линька",
                Scale = 11
            });
            context.CreatureCharacteristics.Add(new CreatureCharacteristic()
            {
                Id = (int)CreatureCharacteristics.Trainability,
                CreatureTypeId = (int)CreatureTypes.Dog,
                NameEn = "Trainability",
                NameRu = "Обучаемость",
                Scale = 11
            });
            context.CreatureCharacteristics.Add(new CreatureCharacteristic()
            {
                Id = (int)CreatureCharacteristics.Watchdog,
                CreatureTypeId = (int)CreatureTypes.Dog,
                NameEn = "Watchdog",
                NameRu = "Сторожевые качества",
                Scale = 11
            });
            context.CreatureCharacteristics.Add(new CreatureCharacteristic()
            {
                Id = (int)CreatureCharacteristics.Guard,
                CreatureTypeId = (int)CreatureTypes.Dog,
                NameEn = "Guard",
                NameRu = "Защитник",
                Scale = 1
            });
            context.CreatureCharacteristics.Add(new CreatureCharacteristic()
            {
                Id = (int)CreatureCharacteristics.Flutty,
                CreatureTypeId = (int)CreatureTypes.Dog,
                NameEn = "Flutty",
                NameRu = "Мягкая шерсть",
                Scale = 1
            });
            context.CreatureCharacteristics.Add(new CreatureCharacteristic()
            {
                Id = (int)CreatureCharacteristics.LowShadding,
                CreatureTypeId = (int)CreatureTypes.Dog,
                NameEn = "Shadding",
                NameRu = "Уровень линьки",
                Scale = 11
            });
        }

        #region system enums
        private void AddRoles(AnmlzDbContext context)
        {
            context.UserRoles.Add(new UserRole() { RoleId = (int)UserRoles.Authority, RoleName = "Authority" });
            context.UserRoles.Add(new UserRole() { RoleId = (int)UserRoles.Admin, RoleName = "Admin" });
            context.UserRoles.Add(new UserRole() { RoleId = (int)UserRoles.User, RoleName = "User" });
        }
        private void AddAccountTypes(AnmlzDbContext context)
        {
            context.UserTypes.Add(new UserType() { Id = (int)UserTypes.Person, NameRu = "Частное лицо", NameEn = "Individual" });
            context.UserTypes.Add(new UserType() { Id = (int)UserTypes.Breeder, NameRu = "Заводчик", NameEn = "Breeder" });
            context.UserTypes.Add(new UserType() { Id = (int)UserTypes.Farm, NameRu = "Питомник", NameEn = "Farm" });
        }
        private void AddCurrencies(AnmlzDbContext context)
        {
            context.Currencies.Add(new Currency()
            {
                Id = (int)Currencies.Rub,
                NameRu = "Руб",
                NameEn = "Rub",
            });

            context.Currencies.Add(new Currency()
            {
                Id = (int)Currencies.Usd,
                NameRu = "Usd",
                NameEn = "Usd",
            });
        }
        private void AddCreatureTypes(AnmlzDbContext context)
        {
            context.CreatureTypes.Add(new CreatureType() { Id = (int)CreatureTypes.Dog, NameRu = "Собака", NameEn = "Dog" });
            context.CreatureTypes.Add(new CreatureType() { Id = (int)CreatureTypes.Cat, NameRu = "Кошка", NameEn = "Cat" });
            context.CreatureTypes.Add(new CreatureType() { Id = (int)CreatureTypes.Ferret, NameRu = "Хорек", NameEn = "Ferret" });
        }
        #endregion system enums
        #region geo
        private void AddCountries(AnmlzDbContext context)
        {
            List<Country> countries = _geoParser.ParseCountries(string.Format("{0}{1}", AppDomain.CurrentDomain.BaseDirectory, "\\Resources\\Geo\\_countries.csv"));
            context.Countries.AddRange(countries);
        }
        private void AddCities(AnmlzDbContext context)
        {
            List<City> cities = _geoParser.ParseCities(string.Format("{0}{1}", AppDomain.CurrentDomain.BaseDirectory, "\\Resources\\Geo\\_cities.csv"));
            context.Cities.AddRange(cities);
        }
        #endregion geo
        private void AddCreatureSizes(AnmlzDbContext context)
        {
            context.CreatureSizeTypes.Add(new CreatureSizeType()
            {
                Id = (int)CreatureSizeTypes.SmallDog,
                NameRu = "Мелкие",
                NameEn = "Small",
                MinWeight = 0,
                MaxWeight = 10,
                CreatureTypeId = (int)CreatureTypes.Dog
            });
            context.CreatureSizeTypes.Add(new CreatureSizeType()
            {
                Id = (int)CreatureSizeTypes.MediumDog,
                NameRu = "Средние",
                NameEn = "Medium",
                MinWeight = 10,
                MaxWeight = 25,
                CreatureTypeId = (int)CreatureTypes.Dog
            });
            context.CreatureSizeTypes.Add(new CreatureSizeType()
            {
                Id = (int)CreatureSizeTypes.LargeDog,
                NameRu = "Крупные",
                NameEn = "Large",
                MinWeight = 25,
                MaxWeight = 45,
                CreatureTypeId = (int)CreatureTypes.Dog
            });
            context.CreatureSizeTypes.Add(new CreatureSizeType()
            {
                Id = (int)CreatureSizeTypes.GiantDog,
                NameRu = "Очень крупные",
                NameEn = "Large",
                MinWeight = 45,
                MaxWeight = 120,
                CreatureTypeId = (int)CreatureTypes.Dog
            });
        }
        private void AddCreatureColors(AnmlzDbContext context)
        {
            //context.CreatureColors.Insert(new CreatureColor()
            //{
            //    Id = 1,
            //    NameRu = "Белый",
            //    Name = "White"
            //});
            //context.CreatureColors.Insert(new CreatureColor()
            //{
            //    Id = 2,
            //    NameRu = "Черный",
            //    Name = "Black"
            //});
        }
        private void AddBreedGroups(AnmlzDbContext context)
        {
            context.BreedGroups.Add(new BreedGroup()
            {
                Id = 1,
                CreatureTypeId = (int)CreatureTypes.Dog,
                NameRu = "Комнатно-декоративные",
                NameEn = "Toy"
            });

            context.BreedGroups.Add(new BreedGroup()
            {
                Id = 2,
                CreatureTypeId = (int)CreatureTypes.Dog,
                NameRu = "Охотничьи (подружейные)",
                NameEn = "Sporting"
            });
            context.BreedGroups.Add(new BreedGroup()
            {
                Id = 3,
                CreatureTypeId = (int)CreatureTypes.Dog,
                NameRu = "Охотничьи (гончие, борзые)",
                NameEn = "Hound"
            });
            context.BreedGroups.Add(new BreedGroup()
            {
                Id = 4,
                CreatureTypeId = (int)CreatureTypes.Dog,
                NameRu = "Терьер)",
                NameEn = "Terrier"
            });
            context.BreedGroups.Add(new BreedGroup()
           {
               Id = 5,
               CreatureTypeId = (int)CreatureTypes.Dog,
               NameRu = "Служебные",
               NameEn = "Working"
           });
            context.BreedGroups.Add(new BreedGroup()
{
    Id = 6,
    CreatureTypeId = (int)CreatureTypes.Dog,
    NameRu = "Овчарка",
    NameEn = "Herding"
});
        }
        private void AddBreeds(AnmlzDbContext context)
        {


            //            context.Breeds.Insert(new Breed()
            //            {
            //                Id = 1,
            //                BreedGroupId = 1,
            //                CreatureTypeId = (int)CreatureTypes.Dog,
            //             //   CreatureCoatId = 1,
            //              //  CreatureColorId = 1,
            //                CreatureSizeTypeId = 1,
            //                NameRu = "Вест Хайленд Вайт Терьер",
            //                Name = "West Highland White Terrier",
            //                DescriptionRu = @"История Вест-хайленд-уайт-терьера началась в XIX веке. Тогда в Шотландии в помёте одного керн терьера появилось несколько белых щенков. Этот факт привлёк внимание селекционеров и один из них занялся разведением белых керн терьеров, которые в дальнейшем были названы вест хайленд уайт терьерами. В Британии этих собачек называют «вести» и у себя на родине они являются одной из наиболее популярных пород.
            //Вест-хайленд-уайт-терьер может вести себя вызывающе, собаки этой породы уверены в себе, стойкие, любят охоту. Вести питает огромную любовь к рытью ям. Собачки этой породы могут лаять без умолку, даже если для лая нет причины. С другими собаками вести храбр, какая бы большая собака ни была с ним рядом, он будет вести себя как равный. Во время каждой прогулки этот терьер воспользуется любой возможностью, чтобы показать свои охотничьи навыки. Он будет охотиться на кого угодно – на соседскую кошку, грызуна или прогуливающихся голубей.
            //Вест хайленд уайт терьер никогда не откажется от прогулки в хорошую погоду, всегда игриво настроен. Вести полно энергии не только на улице, но и в помещении, при этом ему не потребуется много места, чтобы порезвиться. На тот отрезок времени, пока вас нет дома, стоит занять питомца какой-нибудь игрой. С незнакомцами эти собачки ведут себя подозрительно, однако никогда не проявляют агрессии по отношению к людям.
            //Шерсть белого терьера требует тщательного ухода, ведь из-за любви вести к рытью ям её тяжело держать в чистоте. Раз в 3-4 месяца собаку следует тримминговать, волосы на мордочке и ушах необходимо аккуратно состригать. Для чистки шерсти лучше всего подойдёт жесткая щётка.",
            //                Description = @"The West Highland White Terrier, commonly known as the Westie or Westy, is a Scottish breed of dog with a distinctive white coat. The modern breed is descended from a number of breeding programs of white terriers in Scotland prior to the 20th century. Edward Donald Malcolm, 16th Laird of Poltalloch, is credited with the creation of the modern breed from his Poltalloch Terrier, but did not want to be known as such. Other related breeds included George Campbell, 8th Duke of Argyll's Roseneath Terrier and Dr. Americ Edwin Flaxman's Pittenweem Terriers. The breeds of small white Scottish terriers were given its modern name for the first time in 1908, with recognition by major kennel clubs occurring around the same time.
            //The breed remains very popular in the UK and is in the top third of all breeds in the USA since the 1960s. It has been featured in television and film including in Hamish Macbeth and in advertising by companies such as Cesar dog food and Scottish whisky Black & White. It is a medium-sized terrier, although with longer legs than other Scottish breeds of terrier. It has a white double coat of fur which fills out the dog's face giving it a rounded appearance. The breed can be good with children, but will not always tolerate rough handling. The Westie is an active breed, but are social with a high prey drive. They are loyal companions who will go to the ends of the Earth to please their masters.
            //Several breed-specific and non-specific health issues appear in the breed including a condition in young dogs nicknamed ""westie jaw"" which causes an overgrowth of bone in the jaw of the dog. It is also prone to skin disorders, with a breed-specific condition called Hyperplastic Dermatosis occurring. They are very energetic and need plenty of exercise. Cousin to the ""Scotty"", the Westie was bred to hunt small rodents at places such as farms."
            //            });

            //            context.Breeds.Insert(new Breed()
            //            {
            //                Id = 2,
            //                BreedGroupId = 2,
            //                CreatureTypeId = (int)CreatureTypes.Dog,
            //               // CreatureCoatId = 1,
            //               // CreatureColorId = 1,
            //                CreatureSizeTypeId = 1,
            //                NameRu = "Австралийская короткохвостая пастушья собака",
            //                Name = "Australian Cattle Dog",
            //                DescriptionRu = @"Австралийская короткохвостая пастушья собака была выведена в Австралии для работы с диким скотом. Нередко этих собак называют голубыми хилерами – в память о породе собак, отличительной чертой которых было кусать скот за ноги. Породу получили путём скрещивания собак динго, далматина, гладкошерстной высокогорной колли и австралийского келпи. Эти собаки очень выносливые, их можно назвать неутомимыми, из короткохвостой пастушьей собаки получается отличный компаньон. Собаки этой породы очень внимательные и способные, энергичные, бесстрашные и выносливые, по характеру они независимые, но, несмотря на это, послушные и очень преданы своей семье.
            //Шерстный покров прямой и плотный, окрас крапчатый. Часто бывает так, что щенки короткохвостой пастушьей собаки рождаются белыми, но взрослея, темнеют. Окрас варьируется от рыжего до тёмно-серого.
            //Для содержания в городской квартире австралийская короткохвостая пастушья собака не подходит – для поддержания формы представителям этой породы нужно много двигаться.",
            //                Description = @"The Australian Cattle Dog (ACD or Cattle Dog), is a breed of herding dog originally developed in Australia for driving cattle over long distances across rough terrain. In the 19th century, New South Wales cattle farmer Thomas Hall crossed the dogs used by drovers in his parents' home county, Northumberland, with dingoes he had tamed. The resulting dogs were known as Halls Heelers. After Hall's death in 1870, the dogs became available beyond the Hall family and their associates, and were subsequently developed into two modern breeds, the Australian Cattle Dog and the Australian Stumpy Tail Cattle Dog. Robert Kaleski was influential in the Cattle Dog's early development, and wrote the first standard for the breed."
            //            });
        }

        //private void AddFakeData(AnmlzDbContext context)
        //{
        //    int userCounter = 0;
        //    int creatureCounter = 0;
        //    int imageCounter = 0;
        //    int litterCounter = 0;

        //    for (int i = 0; i < 50; i = i + 2)
        //    {
        //        int user1Id = userCounter++;
        //        User usr1 = AddUser(context, user1Id, ref imageCounter);

        //        int user2Id = userCounter++;
        //        User usr2 = AddUser(context, user2Id, ref imageCounter);

        //        bool showClass = rnd.Next(0, 2) > 1 ? true : false;
        //        bool readyToPairing = rnd.Next(0, 2) > 1 ? true : false;


        //        int fatherId = creatureCounter++;
        //        Creature father = CreateCreature(context, fatherId, user1Id,
        //            showClass, true,
        //            readyToPairing, null, null,
        //            new System.DateTime(rnd.Next(2000, 2010),
        //                rnd.Next(1, 12), rnd.Next(1, 28)), ref imageCounter);


        //        int motherId = creatureCounter++;
        //        Creature mother = CreateCreature(context, motherId, user2Id,
        //            showClass, false,
        //            readyToPairing, null, null,
        //            new System.DateTime(rnd.Next(2000, 2010),
        //                rnd.Next(1, 12), rnd.Next(1, 28)), ref imageCounter);

        //        var puppyOwnerId = rnd.Next(0, 2) > 1 ? user1Id : user2Id;
        //        var dateOfBirth = new System.DateTime(2013,
        //                rnd.Next(1, 12), rnd.Next(1, 28));
        //        var price = showClass ? rnd.Next(30000, 45000) : rnd.Next(15000, 30000);

        //        var puppiesCount = rnd.Next(1, 6);

        //        if (puppiesCount > 1)
        //        {
        //            litterCounter++;
        //            context.Litters.Insert(new Litter()
        //            {
        //                Id = litterCounter
        //            });
        //        }

        //        for (int j = 0; j < puppiesCount; j++)
        //        {
        //            int puppyId = creatureCounter++;
        //            bool male = rnd.Next(0, 2) > 1 ? true : false;

        //            Creature puppy = CreateCreature(context, puppyId, puppyOwnerId,
        //            showClass, male,
        //            false, fatherId, motherId, dateOfBirth, ref imageCounter, true, price,
        //            (int)Currencies.Rub, litterId: puppiesCount > 1 ? (int?)litterCounter : null);
        //        }
        //    }
        //}

        //private User AddUser(AnmlzDbContext context, int id, ref int imageCounter)
        //{
        //    imageCounter++;

        //    bool male = rnd.Next(0, 2) > 1 ? true : false;

        //    Image avatar = new Image()
        //    {
        //        Id = imageCounter,
        //        ImageTypeId = (int)ImageTypes.Person,
        //        Name = male ? "man-avatar.png" : "woman-avatar.jpg"
        //    };

        //    context.Images.Insert(avatar);

        //    User user = new User()
        //    {
        //        Id = id,
        //        Name = sampleTextGenerator.GenWords(),
        //        Surname = sampleTextGenerator.GenWords(),
        //        Password = cryptService.HashPassword("12345"),
        //        Email = string.Format("{0}@{0}.com", id),
        //        Phone = "+79210923443",
        //        CountryId = 1,
        //        CityId = 1,
        //        Address = sampleTextGenerator.GenWords(5),
        //        Male = male,
        //        AvatarId = avatar.Id,
        //        Details = sampleTextGenerator.GenWords(10),
        //        AccountTypeId = (int)UserTypes.Breeder
        //    };
        //    context.Users.Insert(user);

        //    UserInRole userInRole = new UserInRole()
        //    {
        //        UserId = user.Id,
        //        RoleId = (int)UserRoles.User
        //    };
        //    ImageToUser imageToUser = new ImageToUser()
        //    {
        //        ImageId = avatar.Id,
        //        UserId = user.Id
        //    };
        //    context.ImageToUsers.Insert(imageToUser);

        //    UserWebsiteUrl websiteUrl = new UserWebsiteUrl()
        //     {
        //         Name = string.Format("{0}.com", sampleTextGenerator.GenWords()),
        //         UserId = id
        //     };
        //    context.UserWebsiteUrls.Insert(websiteUrl);
        //    return user;
        //}

        //private Creature CreateCreature(AnmlzDbContext context, int creatureId, int ownerId,
        //    bool? showClass, bool male, bool readyToPairing, int? fatherId, int? motherId,
        //    DateTime dateOfBirth, ref int imageCounter, bool onSale = false,
        //    int? price = null, int? currencyId = null,
        //    bool passport = true, bool vactinations = true, bool microchip = true, int? litterId = null)
        //{
        //    imageCounter++;

        //    Image avatar = new Image()
        //    {
        //        Id = imageCounter,
        //        ImageTypeId = (int)ImageTypes.Dog,
        //        Name = onSale ? "dog-pet-avatar.png" :
        //        male ? "dog-adult-male-avatar.png" : "dog-adult-female-avatar.png"
        //    };
        //    context.Images.Insert(avatar);

        //    Creature creature = new Creature()
        //    {
        //        Id = creatureId,
        //        Name = sampleTextGenerator.GenWords(),
        //        OfficialName = sampleTextGenerator.GenWords(3),
        //        DateOfBirth = dateOfBirth,
        //        BreedId = 1,
        //        Color = sampleTextGenerator.GenWords(),
        //        Male = male,
        //        Tattoo = sampleTextGenerator.GenWords(),
        //        AuthorId = ownerId,
        //        Description = sampleTextGenerator.GenWords(10),
        //        ShowClass = showClass,
        //        CreatureTypeId = (int)CreatureTypes.Dog,
        //        ReadyToPairing = readyToPairing,
        //        FatherId = fatherId,
        //        MotherId = motherId,
        //        OnSale = onSale,
        //        Price = price,
        //        CurrencyId = currencyId,
        //        AvatarId = avatar.Id,
        //        Passport = passport,
        //        Vaccinations = vactinations,
        //        Microchip = microchip,
        //        LitterId = litterId
        //    };

        //    context.Creatures.Insert(creature);

        //    ImageToCreature imageToCreature = new ImageToCreature()
        //    {
        //        ImageId = avatar.Id,
        //        CreatureId = creature.Id
        //    };
        //    context.ImageToCreatures.Insert(imageToCreature);

        //    return creature;
        //}
    }
}
